package com.geohey.service;

import java.io.InputStream;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.Entity;
import javax.ws.rs.client.WebTarget;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.Form;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;

import org.apache.commons.lang.StringUtils;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.input.SAXBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.geohey.AppContext;
import com.geohey.utils.JerseyUtils;
import com.geohey.utils.JsonUtils;
import com.geohey.utils.SHA1;
import com.geohey.utils.WXMessageUtils;
import com.geohey.wx.LocationInMessage;

@Path("/wxapi")
public class WXApi {

	private Logger logger = LoggerFactory.getLogger(WXApi.class);

	@Context
	protected HttpServletRequest httpServletRequest;

	@Context
	protected HttpServletResponse httpServletResponse;

	private Logger log = LoggerFactory.getLogger(WXApi.class);

	private static final String TOKEN = "geoheyToken";

	@GET
	@Produces("text/html; charset=UTF-8")
	public Response get(@QueryParam("echostr") String echoStr, //
			@QueryParam("signature") String signature, //
			@QueryParam("timestamp") String timestamp, //
			@QueryParam("nonce") String nonce) {

		if (StringUtils.isBlank(echoStr) || StringUtils.isBlank(signature)
				|| StringUtils.isBlank(timestamp) || StringUtils.isBlank(nonce))
			return Response.ok("缺少参数").build();

		String[] a = { TOKEN, timestamp, nonce };
		Arrays.sort(a);
		String str = "";
		for (int i = 0; i < a.length; i++) {
			str += a[i];
		}
		String digest = new SHA1().getDigestOfString(str.getBytes())
				.toLowerCase();
		if (digest.equals(signature)) {
			return Response.ok(echoStr).build();
		} else {
			return Response.ok("认证失败").build();
		}
	}

	@POST
	public Response post() {
		try {
			InputStream is = this.httpServletRequest.getInputStream();
			SAXBuilder builder = new SAXBuilder();
			Document doc = builder.build(is);
			Element root = doc.getRootElement();
			String type = root.getChildText(WXMessageUtils.MSG_TYPE);
			if (type.equals(WXMessageUtils.MSG_TYPE_EVENT)) {
				String value = root.getChildText(WXMessageUtils.EVENT).trim();
				if (value.equals(WXMessageUtils.MSG_EVENT_LOCATION)) {
					LocationInMessage message = LocationInMessage.parse(root);
					String openId = message.getFromUserName();
					double x = message.getX();
					double y = message.getY();
					String createTime = message.getCreateTime();
					boolean saved = pushDataToGeoHey(openId, x, y, createTime);
					if (saved) {
						logger.info(String.format("保存用户{%s}位置成功,x:{%s},y:{%s}",
								openId, x, y));
					} else {
						logger.info(String.format("保存用户{%s}位置失败,x:{%s},y:{%s}",
								openId, x, y));
					}
				}
			}
		} catch (Exception ex) {
			log.error("获取消息失败", ex);
		}
		return Response.ok().build();
	}

	protected boolean pushDataToGeoHey(String openId, double x, double y, String createTime) {
		Form form = new Form();
		Map<String, Object> feature = new HashMap<String, Object>();
		feature.put("geom", new double[] { x, y });
		Map<String, Object> attrs = new HashMap<String, Object>();
		attrs.put("open_id", openId);
		attrs.put("x", x);
		attrs.put("y", y);
		attrs.put("visit_at", createTime);
		feature.put("attrs", attrs);
		String json = JsonUtils.toJson(feature);
		form.param("feature", json);

		String url = AppContext.getInstance().getConfig("app.push.url");
		logger.info("url: " + url);
		Client client = ClientBuilder.newClient();
		WebTarget wt = client.target(url);
		Response resp = wt.request(MediaType.APPLICATION_JSON_TYPE).post(
				Entity.entity(form, MediaType.APPLICATION_FORM_URLENCODED));
		String result = JerseyUtils.readStringAndClose(resp, client);
		logger.info("response: " + result);
		Map map = JsonUtils.readMap(result);
		Object code = map.get("code");
		if (code != null && code.toString().equals("0")) {
			return true;
		}
		return false;
	}
	
}
